<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8" />
    <title>记账系统 - 订单管理（分页 + 统计）</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <style>
        /* 基本重置 */
        * { box-sizing: border-box; }
        body { font-family: "Segoe UI", Roboto, "Helvetica Neue", Arial; background: #f3f6fb; margin: 0; padding: 24px; color: #222; }

        /* 容器 */
        .container { max-width: 1100px; margin: 0 auto; }

        /* 顶部标题 */
        header { display:flex; align-items:center; justify-content:space-between; margin-bottom: 18px; }
        h1 { margin:0; font-size:20px; color:#0b3b6f; }

        /* 卡片风格 */
        .card { background: #fff; border-radius: 12px; box-shadow: 0 6px 16px rgba(15,30,50,0.06); padding: 16px; margin-bottom: 16px; }

        /* 控件排版 */
        .controls { display:flex; gap:12px; flex-wrap:wrap; align-items:center; }
        .controls input[type="text"], .controls select, .controls input[type="date"], .controls input[type="number"] {
            padding: 8px 10px; border-radius: 8px; border: 1px solid #e2e8f0; min-width: 140px;
        }

        .btn {
            background: linear-gradient(180deg,#2563eb,#1d4ed8);
            color:#fff; border: none; padding: 8px 12px; border-radius: 8px;
            cursor:pointer; font-weight:600;
            box-shadow: 0 6px 12px rgba(29,78,216,0.12);
        }
        .btn.secondary {
            background: linear-gradient(180deg,#e6eefc,#dbeeff); color:#0b3b6f; box-shadow:none; font-weight:600;
        }
        .btn.ghost { background:transparent; border:1px solid #e2e8f0; color:#0b3b6f; }

        /* layout: 两列，左列表右表单 */
        .grid { display:grid; grid-template-columns: 1fr 380px; gap: 16px; align-items:start; }

        /* 表格样式 */
        table { width: 100%; border-collapse: collapse; font-size:14px; }
        th, td { padding: 10px 12px; text-align:left; border-bottom: 1px solid #f1f5f9; }
        th { background: #fbfdff; color:#334155; font-weight:600; position:sticky; top:0; }
        tr:hover td { background: #fbfbff; }
        .muted { color:#64748b; font-size:13px; }

        /* 表单右侧 */
        .form-row { margin-bottom:10px; display:flex; gap:8px; align-items:center; }
        .form-row label { width:96px; font-size:14px; color:#0b3b6f; }

        /* 分页 */
        .pager { display:flex; gap:8px; align-items:center; margin-top:12px; }
        .pager .page-num { font-weight:600; padding:6px 10px; border-radius:8px; background:#f8fafc; }

        /* 小的统计卡 */
        .stats { display:flex; gap:12px; margin-top:12px; }
        .stat { background:linear-gradient(180deg,#ffffff,#f8fafc); border-radius:10px; padding:10px; min-width:160px; text-align:center; box-shadow:0 4px 10px rgba(2,6,23,0.04); }
        .stat .value { font-size:18px; font-weight:700; color:#0b3b6f; }
        .stat .label { color:#64748b; font-size:13px; margin-top:6px; }

        /* 响应式 */
        @media (max-width: 900px) {
            .grid { grid-template-columns: 1fr; }
            .form-row label { width:auto; }
        }
    </style>
</head>
<body>
<div class="container">
    <header>
        <h1>记账系统 — 订单管理</h1>
        <div class="muted">后端：Spring Boot + MyBatis &nbsp; • &nbsp; 分页与统计示例</div>
    </header>

    <!-- 筛选与统计卡片 -->
    <div class="card">
        <div style="display:flex; justify-content:space-between; flex-wrap:wrap; gap:12px;">
            <div class="controls" style="align-items:center;">
                <input id="filterProduct" placeholder="按商品名模糊搜索" type="text" />
                <select id="filterStatus">
                    <option value="">所有状态</option>
                    <option value="NOT_SHIPPED">未发货</option>
                    <option value="SHIPPED">已发货</option>
                    <option value="REFUNDED">已退款</option>
                    <option value="DELIVERED">已收货</option>
                </select>

                <select id="sortBy">
                    <option value="">默认排序</option>
                    <option value="price">价格</option>
                    <option value="profit">利润</option>
                    <option value="order_time">下单时间</option>
                    <option value="end_time">结束时间</option>
                </select>
                <select id="sortDir">
                    <option value="desc">降序</option>
                    <option value="asc">升序</option>
                </select>

                <button class="btn" id="btnFilter">筛选 / 排序</button>
                <button class="btn secondary" id="btnReset">重置</button>
            </div>

            <!-- 统计卡 -->
            <div style="display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
                <div class="stats">
                    <div class="stat">
                        <div class="value" id="totalAmountValue">-</div>
                        <div class="label">所有订单总金额</div>
                    </div>
                    <div class="stat">
                        <div class="value" id="profitValue">-</div>
                        <div class="label">按日期计算利润（已收货）</div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 计算统计的表单 -->
        <div style="margin-top:12px; display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
            <label class="muted">金额统计范围：</label>
            <input id="profitStart" type="date" />
            <span class="muted">—</span>
            <input id="profitEnd" type="date" />
            <button class="btn ghost" id="btnCalcProfit">计算金额</button>

            <div style="flex:1"></div>

            <button class="btn ghost" id="btnCalcTotal">刷新总金额</button>
        </div>
    </div>

    <!-- 主体：左列表 右编辑表单 -->
    <div class="grid">
        <!-- 列表 -->
        <div class="card">
            <table id="ordersTable">
                <thead>
                <tr>
                    <th style="width:60px">ID</th>
                    <th>客户</th>
                    <th>商品</th>
                    <th>价格</th>
                    <th>利润</th>
                    <th>状态</th>
                    <th>下单时间</th>
                    <th>结束时间</th>
                    <th style="width:120px">操作</th>
                </tr>
                </thead>
                <tbody></tbody>
            </table>

            <!-- 分页控件 -->
            <div class="pager">
                <button class="btn ghost" id="prevPage">上一页</button>
                <div class="page-num">第 <span id="currentPage">1</span> 页 / 共 <span id="totalPages">1</span> 页</div>
                <button class="btn ghost" id="nextPage">下一页</button>

                <div style="flex:1"></div>

                <label class="muted">每页</label>
                <select id="pageSize">
                    <option value="5">5</option>
                    <option value="10" selected>10</option>
                    <option value="20">20</option>
                    <option value="50">50</option>
                </select>
            </div>
        </div>

        <!-- 右侧表单：新增 / 编辑 -->
        <div class="card">
            <h3 id="formTitle">新增订单</h3>
            <div class="form-row">
                <label>客户名字</label>
                <input id="customerName" placeholder="例如：张三" />
            </div>
            <div class="form-row">
                <label>商品</label>
                <input id="product" placeholder="例如：耳机" />
            </div>
            <div class="form-row">
                <label>价格</label>
                <input id="price" type="number" step="0.01" />
            </div>
            <div class="form-row">
                <label>利润</label>
                <input id="profit" type="number" step="0.01" />
            </div>
            <div class="form-row">
                <label>状态</label>
                <select id="statusInput">
                    <option value="NOT_SHIPPED">未发货</option>
                    <option value="SHIPPED">已发货</option>
                    <option value="REFUNDED">已退款</option>
                    <option value="DELIVERED">已收货</option>
                </select>
            </div>
            <div class="form-row">
                <label>下单时间</label>
                <input id="orderTime" type="datetime-local" />
            </div>
            <div class="form-row">
                <label>结束时间</label>
                <input id="endTime" type="datetime-local" />
            </div>

            <div style="display:flex; gap:8px; margin-top:8px;">
                <button class="btn" id="btnSave">保存</button>
                <button class="btn secondary" id="btnCancel">取消</button>
            </div>
        </div>
    </div>
</div>

<script>
    // ================= 配置 =================
    const API_BASE = 'http://localhost:8080/api/orders'; // 如后端端口不同请改这里
    // 当前分页状态
    let currentPage = 1;
    let pageSize = parseInt(document.getElementById('pageSize').value, 10);
    let totalPages = 1;
    let editingId = null;

    // ================= 工具函数 =================
    function escapeHtml(s) {
        if (s == null) return '';
        return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
    }
    function fmtNum(v) {
        if (v == null) return '-';
        try {
            // toFixed 2 保留两位小数
            return Number(v).toFixed(2);
        } catch(e) { return v; }
    }
    function toLocalInput(datetimeStr) {
        if (!datetimeStr) return '';
        const d = new Date(datetimeStr);
        if (isNaN(d)) return '';
        const y = d.getFullYear();
        const m = String(d.getMonth()+1).padStart(2,'0');
        const day = String(d.getDate()).padStart(2,'0');
        const hh = String(d.getHours()).padStart(2,'0');
        const mm = String(d.getMinutes()).padStart(2,'0');
        return `${y}-${m}-${day}T${hh}:${mm}`;
    }
    function toIsoLocal(datetimeLocalValue) {
        if (!datetimeLocalValue) return null;
        return datetimeLocalValue; // 后端使用 Jackson 解析 ISO-like 字符串
    }

    // ================= 列表（分页） =================
    async function loadPage(page = 1) {
        const product = document.getElementById('filterProduct').value;
        const status = document.getElementById('filterStatus').value;
        const sortBy = document.getElementById('sortBy').value;
        const sortDir = document.getElementById('sortDir').value;
        pageSize = parseInt(document.getElementById('pageSize').value, 10);

        const params = new URLSearchParams();
        params.append('page', page);
        params.append('size', pageSize);
        if (product) params.append('product', product);
        if (status) params.append('status', status);
        if (sortBy) params.append('sortBy', sortBy);
        if (sortDir) params.append('sortDir', sortDir);

        const url = `${API_BASE}/page?${params.toString()}`;
        const res = await fetch(url);
        if (!res.ok) {
            alert('加载列表失败：' + res.status);
            return;
        }
        const data = await res.json();
        // data: { total, page, size, rows }
        renderTable(data.rows || []);
        currentPage = data.page || 1;
        const total = data.total || 0;
        totalPages = Math.max(1, Math.ceil(total / (data.size || pageSize)));
        document.getElementById('currentPage').innerText = currentPage;
        document.getElementById('totalPages').innerText = totalPages;
    }

    function renderTable(orders) {
        const tbody = document.querySelector('#ordersTable tbody');
        tbody.innerHTML = '';
        orders.forEach(o => {
            const tr = document.createElement('tr');
            tr.innerHTML = `
          <td>${o.id}</td>
          <td>${escapeHtml(o.customerName)}</td>
          <td>${escapeHtml(o.product)}</td>
          <td>${fmtNum(o.price)}</td>
          <td>${fmtNum(o.profit)}</td>
          <td>${escapeHtml(o.status)}</td>
          <td>${o.orderTime ? (new Date(o.orderTime)).toLocaleString() : ''}</td>
          <td>${o.endTime ? (new Date(o.endTime)).toLocaleString() : ''}</td>
          <td>
            <button class="btn ghost" onclick="editOrder(${o.id})">编辑</button>
            <button class="btn ghost" onclick="deleteOrder(${o.id})">删除</button>
          </td>
        `;
            tbody.appendChild(tr);
        });
    }

    // 分页按钮事件
    document.getElementById('prevPage').addEventListener('click', () => {
        if (currentPage > 1) { loadPage(currentPage - 1); }
    });
    document.getElementById('nextPage').addEventListener('click', () => {
        if (currentPage < totalPages) { loadPage(currentPage + 1); }
    });
    document.getElementById('pageSize').addEventListener('change', () => {
        loadPage(1);
    });

    // 筛选按钮
    document.getElementById('btnFilter').addEventListener('click', () => {
        loadPage(1);
    });
    document.getElementById('btnReset').addEventListener('click', () => {
        document.getElementById('filterProduct').value = '';
        document.getElementById('filterStatus').value = '';
        document.getElementById('sortBy').value = '';
        document.getElementById('sortDir').value = 'desc';
        loadPage(1);
    });

    // ================= 新增 / 编辑 / 删除 =================
    document.getElementById('btnSave').addEventListener('click', submitForm);
    document.getElementById('btnCancel').addEventListener('click', cancelEdit);

    async function submitForm() {
        const order = {
            customerName: document.getElementById('customerName').value,
            product: document.getElementById('product').value,
            price: parseFloat(document.getElementById('price').value || 0),
            profit: parseFloat(document.getElementById('profit').value || 0),
            status: document.getElementById('statusInput').value,
            orderTime: toIsoLocal(document.getElementById('orderTime').value),
            endTime: toIsoLocal(document.getElementById('endTime').value)
        };

        if (!order.customerName || !order.product) {
            alert('客户名字和商品不能为空');
            return;
        }

        if (editingId) {
            const res = await fetch(`${API_BASE}/${editingId}`, {
                method: 'PUT',
                headers: {'Content-Type':'application/json'},
                body: JSON.stringify(order)
            });
            if (res.ok) {
                alert('更新成功');
                cancelEdit();
                loadPage(currentPage);
                refreshTotalAmount();
            } else {
                alert('更新失败（状态码:' + res.status + '）');
            }
        } else {
            const res = await fetch(API_BASE, {
                method: 'POST',
                headers: {'Content-Type':'application/json'},
                body: JSON.stringify(order)
            });
            if (res.ok) {
                alert('创建成功');
                resetForm();
                loadPage(1);
                refreshTotalAmount();
            } else {
                alert('创建失败（状态码:' + res.status + '）');
            }
        }
    }

    async function editOrder(id) {
        const res = await fetch(`${API_BASE}/${id}`);
        if (!res.ok) { alert('获取失败'); return; }
        const o = await res.json();
        editingId = o.id;
        document.getElementById('formTitle').innerText = '编辑订单 #' + o.id;
        document.getElementById('customerName').value = o.customerName || '';
        document.getElementById('product').value = o.product || '';
        document.getElementById('price').value = o.price ?? '';
        document.getElementById('profit').value = o.profit ?? '';
        document.getElementById('statusInput').value = o.status ?? 'NOT_SHIPPED';
        document.getElementById('orderTime').value = toLocalInput(o.orderTime);
        document.getElementById('endTime').value = toLocalInput(o.endTime);
    }

    async function deleteOrder(id) {
        if (!confirm('确认删除订单 #' + id + ' ?')) return;
        const res = await fetch(`${API_BASE}/${id}`, { method: 'DELETE' });
        if (res.ok) {
            alert('删除成功');
            loadPage(currentPage);
            refreshTotalAmount();
        } else {
            alert('删除失败');
        }
    }

    function cancelEdit() {
        editingId = null;
        document.getElementById('formTitle').innerText = '新增订单';
        resetForm();
    }

    function resetForm() {
        document.getElementById('customerName').value = '';
        document.getElementById('product').value = '';
        document.getElementById('price').value = '';
        document.getElementById('profit').value = '';
        document.getElementById('statusInput').value = 'NOT_SHIPPED';
        document.getElementById('orderTime').value = '';
        document.getElementById('endTime').value = '';
    }

    // ================= 统计功能 =================

    // 计算利润（只统计 DELIVERED，end_time 在日期范围内）
    document.getElementById('btnCalcProfit').addEventListener('click', async () => {
        const start = document.getElementById('profitStart').value;
        const end = document.getElementById('profitEnd').value;
        if (!start || !end) { alert('请选择开始和结束日期（格式：YYYY-MM-DD）'); return; }
        // 调用后端接口： /api/orders/stats/profit?start=YYYY-MM-DD&end=YYYY-MM-DD
        const url = `${API_BASE}/stats/profit?start=${encodeURIComponent(start)}&end=${encodeURIComponent(end)}`;
        const res = await fetch(url);
        if (!res.ok) { alert('统计失败'); return; }
        const data = await res.json();
        document.getElementById('profitValue').innerText = data.totalProfit ?? '0.00';
    });

    // 刷新并展示所有订单总金额
    document.getElementById('btnCalcTotal').addEventListener('click', refreshTotalAmount);
    async function refreshTotalAmount() {
        const res = await fetch(`${API_BASE}/stats/totalAmount`);
        if (!res.ok) { document.getElementById('totalAmountValue').innerText = '-'; return; }
        const data = await res.json();
        document.getElementById('totalAmountValue').innerText = data.totalAmount ?? '0.00';
    }

    // 初始加载
    window.addEventListener('load', () => {
        loadPage(1);
        refreshTotalAmount();
    });

</script>
</body>
</html>
